package org.equinoxosgi.toast.internal.client.emergency;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.equinoxosgi.toast.core.ICoreConstants;
import org.equinoxosgi.toast.core.LogUtility;
import org.equinoxosgi.toast.core.PropertyManager;
import org.equinoxosgi.toast.core.channel.sender.ChannelMessage;
import org.equinoxosgi.toast.core.channel.sender.IChannel;
import org.equinoxosgi.toast.core.emergency.IEmergencyConstants;
import org.equinoxosgi.toast.dev.airbag.IAirbag;
import org.equinoxosgi.toast.dev.airbag.IAirbagListenser;
import org.equinoxosgi.toast.dev.gps.IGps;

public class EmergencyMonitor implements IAirbagListenser {
	private IAirbag airbag;
	private IGps gps;
	private IChannel channel;
	private Job job;

	@Override
	public void deployed() {
		startJob();
	}

	private void runEmergencyProcess() {
		final ChannelMessage message = new ChannelMessage(IEmergencyConstants.EMERGENCY_FUNCTION);
		final String id = PropertyManager.getProperty(ICoreConstants.ID_PROPERTY, ICoreConstants.ID_DEFAULT);
		message.addParameter(ICoreConstants.ID_PARAMETER, id);
		message.addParameter(IEmergencyConstants.LATITUDE_PARAMETER, gps.getLatitude());
		message.addParameter(IEmergencyConstants.LONGITUDE_PARAMETER, gps.getLongitude());
		message.addParameter(IEmergencyConstants.HEADING_PARAMETER, gps.getHeading());
		message.addParameter(IEmergencyConstants.SPEED_PARAMETER, gps.getSpeed());
		InputStream stream = null;
		try {
			stream = channel.send(message);
			final InputStreamReader reader = new InputStreamReader(stream);
			try {
				final BufferedReader buffer = new BufferedReader(reader);
				final String reply = buffer.readLine();
				LogUtility.logDebug(this, "Received reply: " + reply);
			} finally {
				stream.close();
			}
		} catch (final IOException e) {
			LogUtility.logError(this, "Unable to send to back end: ", e);
		}
		job = null;
	}

	public void setAirbag(final IAirbag airbag) {
		this.airbag = airbag;
	}

	public void setChannel(final IChannel channel) {
		this.channel = channel;
	}

	public void setGps(final IGps gps) {
		this.gps = gps;
	}

	public void shutdown() {
		stopJob();
		airbag.removeListener(this);
		System.out.println("Emergency monitor terminated.");
	}

	private void startJob() {
		if (job != null) {
			return;
		}
		job = new Job("EmergencyMonitor") {
			@Override
			protected IStatus run(final IProgressMonitor monitor) {
				runEmergencyProcess();
				return Status.OK_STATUS;
			}
		};
		job.schedule();
	}

	public void startup() {
		System.out.println("Emergency monitor launch...");
		airbag.addListener(this);
	}

	private void stopJob() {
		if (job != null) {
			job.cancel();
			try {
				job.join();
			} catch (final InterruptedException e) {
				// shutting down, ok to ignore
			}
			job = null;
		}
	}
}
